import time
import datetime
import string
import random
from urllib import parse
import math

from django.conf import settings
from math import radians, cos, sin, asin, sqrt, degrees, pi


def full_zero(num, max_length=10):
    num = str(num)
    num_length = len(num)
    return "0" * (max_length - num_length) + num


def get_lng_lat_tuple(lng, lat, dis=50, earth_radius=6371):
    lng = float(lng)
    lat = float(lat)
    # 正北 纬度发生变
    top = (lng, lat + 180 * dis / (earth_radius * pi))  # 纬度变大 经度不变，
    # 正南
    bottom = (lng, lat - 180 * dis / (earth_radius * pi))  # 纬度变大 经度不变，
    # 正东
    right = (lng + 180 * dis / (earth_radius * pi * cos(radians(lat))), lat)
    # 正西
    left = (lng - 180 * dis / (earth_radius * pi * cos(radians(lat))), lat)
    return top, bottom, left, right

    # dlng = 2 * asin(sin(dis) / (2 * earth_radius)) / cos(degrees(lat))
    # dlng = radians(dlng)
    # dlat = dis / earth_radius
    # dlat = radians(dlat)
    # # lng  经度 竖
    # # lat 纬度 横
    # left = (lng - dlng, lat)  # 纬度不变 经度变大，
    # right = (lng + dlng, lat)  # 纬度不变 经度变小，
    # bottom = (lng, lat - dlat)  # 纬度变小 经度不变，
    # top = (lng, lat + dlat)  # 纬度变大 经度不变，
    # return top, bottom, left, right


def geodistance(lng1, lat1, lng2, lat2):
    lng1, lat1, lng2, lat2 = float(lng1), float(lat1), float(lng2), float(lat2)
    lng1, lat1, lng2, lat2 = map(radians, [lng1, lat1, lng2, lat2])
    dlon = lng2 - lng1
    dlat = lat2 - lat1
    a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
    dis = 2 * asin(sqrt(a)) * 6371 * 1000
    return dis


class FuncUtils:
    @property
    def unique_value(self):
        now = datetime.datetime.now()
        value = '{0}{1}'.format(
            now.strftime('%y%m%d%H%M%S%f'),
            random.randint(10, 100)
        )
        return value

    @classmethod
    def is_float(cls, x):
        try:
            float(x)
            return True
        except ValueError:
            return False

    @classmethod
    def get_decimals(cls, x):
        return len(str(x).split('.')[1])

    def makeCouponCode(cls, prefix='', length=4):
        originCode = string.ascii_lowercase
        words = prefix
        if length == 0:
            pass
        for index in range(length):
            words += random.choice(originCode)

        s = str(int(time.time() * 10000))
        base = 0
        base_str = ""
        for i in range(2, len(s), 2):
            j = s[base:i]
            if 91 > int(j) >= 65:
                w = chr(int(j))
                base_str += w
            else:
                base_str += j
            base = i
        base_str += words
        return base_str


def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
              encoding='utf-8', errors='replace'):
    qs, _coerce_result = parse._coerce_args(qs)
    pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
    r = []
    for name_value in pairs:
        if not name_value and not strict_parsing:
            continue
        nv = name_value.split('=', 1)
        if len(nv) != 2:
            if strict_parsing:
                raise ValueError("bad query field: %r" % (name_value,))
            # Handle case of a control-name with no equal sign
            if keep_blank_values:
                nv.append('')
            else:
                continue
        if len(nv[1]) or keep_blank_values:
            name = nv[0]
            name = parse.unquote(name, encoding=encoding, errors=errors)
            name = _coerce_result(name)
            value = nv[1]
            value = parse.unquote(value, encoding=encoding, errors=errors)
            value = _coerce_result(value)
            r.append((name, value))
    return r


def round_custom(num, to_fixed):
    """
    :param num:
    :param to_fixed: 要保留的小数
    :return:
    """
    if not isinstance(to_fixed, int):
        raise TypeError("to_fixed 只能是数字")
    if to_fixed == 0:
        return num
    else:
        if isinstance(num, float):
            j = "0." + "0" * to_fixed + "5"
            k = "1" + "0" * to_fixed
            b = num + float(j)
            b = math.floor(b * float(k))
            r = round(b / float(k), to_fixed)
            return r
        else:
            raise TypeError("num 只能是小数")


def noise_arcs(draw, image):
    size = image.size
    draw.arc([-20, -20, size[0], 20], 0, 295, fill=settings.CAPTCHA_FOREGROUND_COLOR)
    draw.line([-20, 20, size[0] + 20, size[1] - 20], fill=settings.CAPTCHA_FOREGROUND_COLOR)
    # draw.line([-20, 0, size[0] + 20, size[1]], fill=settings.CAPTCHA_FOREGROUND_COLOR)
    return draw


def unique_code():
    s = string.ascii_letters
    map_group = {i: [] for i in range(10)}
    for i in range(len(s)):
        map_group[i % 10].append(s[i])
    now = datetime.datetime.now()
    value = '{0}{1}'.format(
        now.strftime('%y%m%d%H%M%S%f'),
        "".join(random.sample(s, 3)),
    )
    g = random.sample(range(15), 10)
    value = list(value)
    for i in g:
        k = value[i]
        word = random.choices(map_group.get(int(k)))
        value[i] = "".join(word)
    return "".join(value)


funcUtils = FuncUtils()
if __name__ == '__main__':
    a = get_lng_lat_tuple(114.07101830688478, 22.5559875812593)
    print(a)
